-------------------------------------------------------------------------------
-- Title      : Decimal digit scanner for four seg7s of Nexys 2 
-- Project    : lab 5
-------------------------------------------------------------------------------
-- File       : seg7Scanner.vhd
-- Author     : Paul Winslow
-- Company    : 
-- Created    : 2012-09-29
-- Last update: 2012-11-24
-- Platform   : 
-- Standard   : VHDL'93
-------------------------------------------------------------------------------
-- Description: Takes in four, 4-bit hex numbers and outputs them to the four
--              Nexys 2 seg7s, appropriately scanning the anodes.
-------------------------------------------------------------------------------
-- Copyright (c) 2012 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2012-09-29  1.0      paul    Created
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

package seg7Scanner_CMP is
  component seg7Scanner is
    port (
      in_clk     : in  std_logic;
      in_rst     : in  std_logic;
      in_load    : in  std_logic;
      in_dig0    : in  std_logic_vector(3 downto 0);
      in_dig1    : in  std_logic_vector(3 downto 0);
      in_dig2    : in  std_logic_vector(3 downto 0);
      in_dig3    : in  std_logic_vector(3 downto 0);
      out_seg7   : out std_logic_vector(7 downto 0);
      out_anodes : out std_logic_vector(3 downto 0));
  end component seg7Scanner;
end package seg7Scanner_CMP;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.decodeSeg7_CMP.all;

entity seg7Scanner is
  
  port (
    in_clk     : in  std_logic;
    in_rst     : in  std_logic;
    in_load    : in  std_logic;
    in_dig0    : in  std_logic_vector(3 downto 0);
    in_dig1    : in  std_logic_vector(3 downto 0);
    in_dig2    : in  std_logic_vector(3 downto 0);
    in_dig3    : in  std_logic_vector(3 downto 0);
    out_seg7   : out std_logic_vector(7 downto 0);
    out_anodes : out std_logic_vector(3 downto 0));

end entity seg7Scanner;

architecture rtl of seg7Scanner is

  constant INTERVAL : integer := 50000;

  signal dig0  : std_logic_vector(3 downto 0);
  signal dig1  : std_logic_vector(3 downto 0);
  signal dig2  : std_logic_vector(3 downto 0);
  signal dig3  : std_logic_vector(3 downto 0);
  signal segIn : std_logic_vector(3 downto 0);  -- Input to decodeSeg7

  signal scanCnt     : natural range 0 to INTERVAL;
  signal activeAnode : unsigned(1 downto 0);
  
begin  -- architecture rtl

  -- Register the inputs when 'load' issued
  regInputs_proc : process (in_clk, in_rst) is
  begin  -- process regInputs
    if in_rst = '1' then                -- asynchronous reset (active high)
      dig0 <= (others => '0');
      dig1 <= (others => '0');
      dig2 <= (others => '0');
      dig3 <= (others => '0');
    elsif rising_edge(in_clk) then      -- rising clock edge
      if in_load = '1' then
        dig0 <= in_dig0;
        dig1 <= in_dig1;
        dig2 <= in_dig2;
        dig3 <= in_dig3;
      end if;
    end if;
  end process regInputs_proc;

  -- Scan the anodes about 1KHz, assuming 50 MHz clk
  scanInterval_proc : process (in_clk, in_rst) is
  begin  -- process scanInterval
    if in_rst = '1' then                -- asynchronous reset (active high)
      scanCnt     <= 0;
      activeAnode <= (others => '0');
    elsif rising_edge(in_clk) then      -- rising clock edge
      scanCnt <= scanCnt + 1;
      if (scanCnt = INTERVAL-1) then
        activeAnode <= activeAnode + 1;
        scanCnt     <= 0;
      end if;
    end if;
  end process scanInterval_proc;

  -- Map the outputs
  mapOutputs_proc : process (in_clk, in_rst) is
  begin  -- process mapOutputs_proc
    if in_rst = '1' then
      out_anodes <= "0000";
      segIn      <= x"E";
    elsif rising_edge(in_clk) then
      case activeAnode is
        when "00" =>
          out_anodes <= "1110";         -- Left most digit
          segIn      <= dig0;
        when "01" =>
          out_anodes <= "1101";
          segIn      <= dig1;
        when "10" =>
          out_anodes <= "1011";
          segIn      <= dig2;
        when "11" =>
          out_anodes <= "0111";         -- Right most digit
          segIn      <= dig3;
        when others =>                  -- Turn everything off
          out_anodes <= "1111";
          segIn      <= "1111";
      end case;
    end if;
  end process mapOutputs_proc;

  -- Decode the 7 segment before output
  decode7Seg_U : decode7Seg
    port map (
      in_bin  => segIn,
      out_bin => open,
      out_dec => out_seg7);

end architecture rtl;
